package services

import (
	"errors"
	"os"
	"sync"
	"time"
)

type ClientParameter struct {
	Directory  string
	Command    string
	Timeout    int
	TaskId     int
	ScheduleId int
	Mode       int
	ClientId   int
}

const (
	StatusStart = 1 // 启动
	StatusStop  = 2 // 停止
	StatusPause = 3 //暂停
)

type ClientSupervisorTask struct {
	ClientParameter *ClientParameter
	Process         *os.Process
	Status          int
	Error           error
	DeadCount       int
	LastDeadAt      time.Time
}

// ClientSupervisorTaskManage 客户端守护进程管理
type ClientSupervisorTaskManage struct {
	List   []*ClientSupervisorTask
	Status bool
	mu              sync.Mutex
}

// 单例
var clientSupervisorTaskManageInstance *ClientSupervisorTaskManage

var once sync.Once

// Add 添加任务
func (m *ClientSupervisorTaskManage) Add(clientParameter *ClientParameter) {
	exist, _ := m.Exist(clientParameter.TaskId)
	if exist {
		return
	} else {
		m.mu.Lock()
		defer m.mu.Unlock()

		m.List = append(m.List, &ClientSupervisorTask{
			ClientParameter: clientParameter,
			Process:         nil,
			Status:          StatusPause,
		})
	}
	if m.Status == true {
		go Exec(*clientParameter)
	}
}

// Reload 更新守护进程
func (m *ClientSupervisorTaskManage) Reload(clientParameter *ClientParameter) error {
	exist, index := m.Exist(clientParameter.TaskId)
	if !exist {
		return errors.New("该任务不存在")
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	isStart := false
	if m.List[index].Status == StatusStart {
		isStart = true
	}

	if isStart {
		_ = m.List[index].Process.Kill()
	}
	m.List = append(m.List[:index], m.List[index+1:]...)

	if isStart {
		m.Add(clientParameter)
	}
	return nil
}

// Pause 暂停任务
func (m *ClientSupervisorTaskManage) Pause(taskId int) error {
	exist, index := m.Exist(taskId)
	if !exist {
		return errors.New("该任务不存在")
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	_ = m.List[index].Process.Kill()
	m.List[index].Status = StatusPause
	return nil
}

func (m *ClientSupervisorTaskManage) Process(taskId int, process *os.Process) {
	if m.List == nil {
		return
	}
	for _, supervisor := range m.List {
		if supervisor.ClientParameter.TaskId == taskId {
			supervisor.Status = StatusStart
			supervisor.Process = process
			break
		}
	}
}

// Stop 停止指定任务
func (m *ClientSupervisorTaskManage) Stop(taskId int) {
	if m.Status == false {
		return
	}
	exist, index := m.Exist(taskId)
	if !exist {
		return
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	if m.List[index].Status == StatusStart {
		_ = m.List[index].Process.Kill()
	}
	m.List[index].Status = StatusStop
}

// AllStart 全部启动
func (m *ClientSupervisorTaskManage) AllStart() {
	m.Status = true
	if m.List == nil {
		return
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	for _, supervisor := range m.List {
		if supervisor.Status == StatusPause {
			go Exec(*supervisor.ClientParameter)
		}
	}
}

// AllStop 全部暂停
func (m *ClientSupervisorTaskManage) AllStop() {
	if m.Status == false {
		return
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	m.Status = false
	for _, supervisor := range m.List {
		if supervisor.Status == StatusStart {
			_ = supervisor.Process.Kill()
		}
		supervisor.Status = StatusStop
	}
}

// Exist 判断任务是否存在
func (m *ClientSupervisorTaskManage) Exist(taskId int) (bool, int) {
	m.mu.Lock()
	defer m.mu.Unlock()

	if m.List == nil {
		return false, 0
	}
	exist := false
	index := 0
	for i, supervisor := range m.List {
		if taskId == supervisor.ClientParameter.TaskId {
			exist = true
			index = i
			break
		}
	}
	return exist, index
}

// Refresh 重启暂停任务
func (m *ClientSupervisorTaskManage) Refresh() {
	for true {
		time.Sleep(1 * 1e9)
		if m.List == nil || m.Status == false {
			continue
		}
		for _, supervisor := range m.List {
			if supervisor == nil {
				continue
			}
			if supervisor.Status == StatusPause {
				go Exec(*supervisor.ClientParameter)
			}
		}
	}
}

// GetClientSupervisorTaskManageInstance 获取任务管理模型
func GetClientSupervisorTaskManageInstance() *ClientSupervisorTaskManage {
	once.Do(func() {
		clientSupervisorTaskManageInstance = &ClientSupervisorTaskManage{
			List:   nil,
			Status: false,
		}
	})
	return clientSupervisorTaskManageInstance
}
